<template>
	<div class="upload-file">
		<div v-if="!disabled" class="upload-file__action-area">
			<template v-if="isMaxFileCount">
				<div v-if="uploadType==='native'"
					:class="['upload__drag-range', {
						'is-disabled': isMaxFileCount
					}]"
				>
					<span class="upload-add-icon">+</span>
				</div>
			</template>
			<template v-else>
				<a-popover v-model:visible="carmeraVisible" trigger="click">
					<template #content>
						<div class="upload-file__camera-tool-cell" @click="onCameraClick">拍照</div>
						<div class="upload-file__camera-tool-cell" @click="onLibaryClick">从相册选择</div>
					</template>
					<div v-if="uploadType==='native'"
						:class="['upload__drag-range', {
							'is-disabled': isMaxFileCount
						}]"
					>
						<span class="upload-add-icon">+</span>
					</div>
				</a-popover>
				<div v-if="uploadType!=='native'"
					:class="['upload__drag-range', {
						'is-disabled': isMaxFileCount
					}]"
					@click="onAddClick"
					@mouseenter="onAddMouseEnter"
					@mouseleave="onAddMouseleave"
				>
					<span class="upload-add-icon">+</span>
				</div>
			</template>
			<div class="upload__info">
				<div>最多上传{{maxCount}}个文件，单个文件不超过{{maxSize}}M</div>
				<div>支持格式：</div>
				<div>{{acceptText}}</div>
			</div>
		</div>
		<div class="upload-file__max-tip">{{uploadMessage}}</div>
		<div class="upload-file__file-ul">
			<div v-for="(item, index) in fileList" :key="index" class="file-list__block">
				<w-image :src="item.url" class="block-image" @click="onPreviewClick(item.url)"></w-image>
				<a-popconfirm
					title="确认后，附件内容将被删除，确认是否删除？"
					@confirm="onFileDelClick(item, index)"
				>
					<w-icon
						v-if="!disabled"
						type="delete-icon"
						size="mini"
						pointer
						class="delete-btn"
					></w-icon>
				</a-popconfirm>
			</div>
		</div>
		<input type="file" ref="uploadFileRef" name="file" :accept='accept' capture="environment" style="display: none" @change="onFileChange"/>
	</div>
</template>
<script lang="ts">
/**
 * upload by shang 2022/5/5
 * @desc upload 上传文件组件
 * @params [String] action 请求url
 * @params [Array] fileList 文件list
 * @params [number] maxCount 最大文件数
 * @params [number] maxSize 文件体积
 * @params [string] fileType 文件类型
 * @params [Boolean] disabled 是否禁用上传
 */
import { computed, defineComponent, ref } from 'vue'
import type { PropType } from 'vue'
import { getFxInstance } from '@/js/instance'
import uploadFIleConfig from '../../ts/config/upload_file_config'
import type { FileType } from '../../ts/config/upload_file_config'
export default defineComponent({
	name: 'wind-link',
	props: {
		uploadApi: {
			type: Function,
			default: () => {
				return Promise.resolve()
			}
		},
		fileList: {
			type: Array as PropType<{url: string}[]>,
			default: () => {
				return []
			}
		},
		maxCount: {
			type: Number,
			default: 3
		},
		maxSize: {
			type: Number,
			default: 1
		},
		fileType: {
			type: String as PropType<FileType>,
			default: 'image'
		},
		disabled: Boolean,
		uploadType: {
			type: String,
			default: 'native'
		}

	},
	emits: ['change', 'on-image-preview-click'],
	setup (props, { emit }) {
		const fxInstance = getFxInstance()
		const uploadFileRef = ref<HTMLInputElement|null>(null)
		const accept = computed(() => {
			let _accept = ''
			switch (props.fileType) {
				case 'file':
					_accept = '*'
					break
				case 'image':
					_accept = 'image/gif, image/jpeg, image/png'
					break
				case 'word':
					_accept = '.doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document'
					break
				case 'excel':
					_accept = '.xls,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel'
					break
				case 'video':
					_accept = 'audio/mp4,application/ogg,audio/ogg,.webm'
					break
			}
			return _accept
		})
		const acceptText = computed(() => {
			return (uploadFIleConfig[props.fileType] || []).join('，')
		})
		const isMaxFileCount = computed(() => {
			return props.fileList.length >= props.maxCount
		})
		const uploadMessage = computed(() => {
			const message = `已上传${props.fileList.length}个附件`
			const maxMessage = isMaxFileCount.value ? ', 已达到最大上传数量' : ''
			return `${message}${maxMessage}`
		})
		const onFileChange = function () {
			onFileUpload(uploadFileRef.value!.files![0])
		}
		const onFileUpload = function (file:File) {
			const typeName = file.name.substring(file.name.lastIndexOf('.')).toLowerCase()
			if (!uploadFIleConfig[props.fileType].includes(typeName)) {
				fxInstance.$fxMessage.warning(`只支持格式为：${uploadFIleConfig[props.fileType].join('，')}的文件`)
				return false
			}
			if (file.size > props.maxSize * 1024 * 1024) {
				fxInstance.$fxMessage.warning(`文件大小不能超过${props.maxSize}MB`)
				return false
			}
			onFileUploadHandler(file).then(res => {
				const fileList = props.fileList
				fileList.push(res)
				emit('change', fileList)
			})
		}
		const onFileUploadHandler = function (file:File):Promise<{url:string, name:string}> {
			return props.uploadApi(file).then((res:string) => {
				const val = {
					url: res
				}
				return Promise.resolve(val)
			})
		}
		const onAddClick = function () {
			if (props.disabled || isMaxFileCount.value) {
				return false
			}
			uploadFileRef.value!.value = ''
			uploadFileRef.value!.click()
		}
		const mouseEnterFlag = ref(false)
		const onAddMouseEnter = function () {
			if (isMaxFileCount.value) {
				return false
			}
			mouseEnterFlag.value = true
		}
		const onAddMouseleave = function () {
			if (isMaxFileCount.value) {
				return false
			}
			mouseEnterFlag.value = false
		}
		const onFileDelClick = function (file:unknown, index:number) {
			const fileList = props.fileList
			fileList.splice(index, 1)
			emit('change', fileList)
		}
		const onPreviewClick = function (url:string) {
			const typeName = url.substring(url.lastIndexOf('.')).toLowerCase()
			if (!uploadFIleConfig.image.includes(typeName)) {
				fxInstance.$fxMessage.warning(`只支持预览格式为：${uploadFIleConfig.image.join('，')}的文件`)
				return false
			}
			emit('on-image-preview-click', url)
		}
		const carmeraVisible = ref(false)
		const onCameraClick = () => {
			if (props.disabled || isMaxFileCount.value) {
				return false
			}
			carmeraVisible.value = false
			fxInstance.$fxCordova.camera.getPicture().then(onFileUpload)
		}
		const onLibaryClick = () => {
			if (props.disabled || isMaxFileCount.value) {
				return false
			}
			carmeraVisible.value = false
			fxInstance.$fxCordova.camera.getPictureByLibary().then(onFileUpload)
		}
		return {
			onFileChange,
			accept,
			acceptText,
			uploadMessage,
			uploadFileRef,
			onAddClick,
			isMaxFileCount,
			onAddMouseEnter,
			onAddMouseleave,
			mouseEnterFlag,
			onFileDelClick,
			onPreviewClick,
			carmeraVisible,
			onCameraClick,
			onLibaryClick
		}
	}
})
</script>
<style lang="scss" scoped>
@import "../../style/varsty";
.upload-file {
    flex: 1;
    display: flex;
    flex-direction: column;
    .upload-file__action-area {
        flex-direction: row;
        display: flex;
        height: 110px;
        .upload__drag-range {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-right: 20px;
            margin-bottom: 10px;
            padding-right: 10px;
            padding-left: 10px;
            width: 100px;
            height: 100px;
            border: 1px dashed #c9cdd4;
            border-radius: 5px;
            color: #e2e2e2;
            background-color: #f7f8fa;
            flex-direction: row;
            box-sizing: border-box;
            cursor: pointer;
            &.is-disabled {
                border-color: #eeeeee;
                color: #999999;
                background-color: #eeeeee;
                cursor:not-allowed;
            }
            .upload-add-icon {
                font-size: 30px;
            }
        }
        .upload__info {
            flex: 1;
            font-size: 12px;
        }
    }
    .upload-file__max-tip {
        height: 30px;
        line-height: 30px;
    }
    .upload-file__file-ul {
        display: flex;
        overflow: auto;
        padding-top:10px;
        flex:1;
        flex-flow: row wrap;
        box-sizing:border-box;
        .file-list__block {
            position: relative;
            display: flex;
            align-items: center;
            margin-right: 10px;
            margin-bottom: 10px;
            width: 100px;
            height: 100px;
            border-radius: 6px;
            background-color: #f2f3f5;
            flex-direction: row;
            box-sizing: border-box;
            .block-image {
                width: 100%;
                height: 100%;
                border-radius: 6px;
            }
            .delete-btn {
                position: absolute;
                top:-10px;
                right: -10px;
                width: 20px;
                height: 20px;
            }
        }
    }
}
.upload-file__camera-tool-cell {
    width: 150px;
    height:  50px;
    font-size: 15px;
    line-height: 50px;
    &:first-child {
        border-bottom: 1px solid #eeeeee;
    }
}
</style>
